defmodule ShortEner.Router do
  use Plug.Router
  use Plug.Debugger

  import Ecto.Query, warn: false

  require Logger
  alias Logger, as: LOG

  alias DbSupport.Mnesia.Repo, as: Repo
  alias Ziply.Links
  #IO.inspect Repo

  alias Common.ShortenEr, as: Sor

  @db_impl Application.get_env(:short_ener, :data_provider)
  @author Application.get_env(:short_ener, :author)
  @aname Application.get_env(:short_ener, :aname)
  @ver Application.get_env(:short_ener, :ver)
  @usage Application.get_env(:short_ener, :usage)
  

  plug Plug.Logger, log: :debug
  plug Plug.Parsers, parsers: [:urlencoded, :multipart]
  
  plug :match
  plug :dispatch

  get "/" do
    send_resp(conn, 200, 
      "Welcome #{@usage}\nby #{@author} as #{@aname}v.#{@ver}\n")
  end

  get "/ping" do
    send_resp(conn, 200, 
      "pong ;-)\nI'm alive.\nby #{@author} as #{@aname}v.#{@ver}\n")
  end

  post "/api" do
    {status, body} =
      case conn.body_params do
        %{"url" => events} -> {200, gen_ziply(events)}
        _ -> {422, missing_events()}
      end
    send_resp(conn, status, body)
  end

  defp append_uri!(uri, hashid) do
    next_id = @db_impl.next_id("ser_link")
    LOG.debug ":next_id:#{next_id}"
    result = %{
      "orig_url" => uri,
      "hashid" => hashid,
    }

    %Links{}
    |> Links.changeset(Map.put(result, "id", next_id))
    |> Repo.insert!()
  end

  defp gen_ziply(uri) do
    #LOG.debug("body: #{uri}")
    hashid = Sor.generate()
    # check had ziped ?
    ziped = Repo.get_by(Links, orig_url: uri)
    case ziped do
      %Links{} ->
        LOG.debug "had ziped url"
        IO.inspect ziped.hashid
        "Ziped: t.101.s/#{ziped.hashid} ~> #{uri} \n"
      nil ->
        LOG.debug "new url"
        LOG.debug "#{hashid} ~> #{uri}"
        append_uri!(uri, hashid)
        "Ziply: t.101.s/#{hashid} ~> #{uri} \n"
      end
  end

  defp missing_events do
    "error: ~ NEED as\n\t -X POST -d 'url'='http://...'\n"
  end

  match _ do
    #LOG.debug("request_path: #{conn.request_path}")
    hashid = String.slice(conn.request_path, 1, 6)
    #LOG.debug("hashid: #{hashid}")
    ziped = Repo.get_by(Links, hashid: hashid)
    case ziped do
      %Links{} ->
        IO.inspect ziped.orig_url
        post = Ecto.Changeset.change ziped, touch: ziped.touch+1
        case Repo.update post do
          {:ok, struct}       -> # Updated with success
            IO.inspect struct
            conn 
            |> Plug.Conn.resp(:found, "") 
            |> Plug.Conn.put_resp_header("location",
                                        ziped.orig_url)
          {:error, changeset} -> # Something went wrong
            IO.inspect changeset
          end
      nil ->
        #LOG.debug "nil matched"
        send_resp(conn, 404, "Oops...Nothing here :(\n")
      end
    end

end

